#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>

#define MAXBUF  8192

typedef void handler_t(int);

void handler(int sig)
{
    pid_t pid;
    sigset_t sigset, old_sigset;

    while ((pid = waitpid(-1, NULL, 0)) > 0)
        printf("Handler reaped child %d\n", (int)pid);
    
    if (errno != ECHILD)
    {
        printf("waitpid error: %s\n", strerror(errno));
        exit(0);
    }

    /*sigemptyset(&sigset);
    sigprocmask(SIG_BLOCK, &sigset, &old_sigset);

    printf("SIGCHLD %s the old block set!\n", 
        sigismember(&old_sigset, SIGCHLD)?"in":"out");
    printf("SIGINT %s the old block set!\n", 
        sigismember(&old_sigset, SIGINT)?"in":"out");

    if ((pid = waitpid(-1, NULL, 0)) < 0)
    {
        printf("waitpid error: %s\n", strerror(errno));
        exit(0);
    }

    printf("Handler reaped child %d\n", (int)pid);*/

    return;
}

handler_t *Signal(int signum, handler_t *handler)
{
    struct sigaction action, old_action;

    action.sa_handler = handler;
    sigemptyset(&action.sa_mask);
    sigaddset(&action.sa_mask, SIGINT);
    action.sa_flags = SA_RESTART;

    if (sigaction(SIGCHLD, &action, &old_action) < 0)
    {
        printf("sigaction error: %s\n", strerror(errno));
        exit(0);
    }

    return old_action.sa_handler;
}


int main()
{
    int i, n;
    char buf[MAXBUF];
    
    if (Signal(SIGCHLD, handler) == SIG_ERR)
    {
        printf("signal error!\n");
        exit(0);
    }

    for (i = 0; i < 3; i ++)
    {
        if (fork() == 0)
        {
            printf("Hello from child %d\n", (int)getpid());
            sleep(1);
            exit(0);
        }
    }

    /* parent waits for terminal input and then process it */
    while (n = read(STDIN_FILENO, buf, sizeof(buf)) < 0)
    {
        if (errno != EINTR)
        {
            printf("read error: %s\n", strerror(errno));
            exit(0);
        }
    }

    printf("Parent processing input!\n");
    pause();

    return 0;
}
